/**
 * @author Austin Andrews (Templarian)
 * @authorurl http://templarian.com
 * @framework DD Framework
 * @licence MIT License
 * @licenceurl http://ddframework.googlecode.com/svn/trunk/license.txt
 * @overview Easily handle navigating around page.
 */
dd.navigate({
    // Hold the last record
    _t:"",
    fn:{
        navigate:function()
        {
            var a = [].slice.call(arguments, 0);
            if(this.self.nodeName == "a")
            {
                var link = a.join("/");
                dd(this).setAttribute("href", link == "" ? "" : a.join("/") + "/");
            }
            dd(this).event({
                click:function()
                {
                    dd.navigate.apply({}, this.a);
                }
            }, {a:a});
        }
    },
    path:[],
    /**
     * Navigate to a page.
     * @namespace dd.navigate
     * @function
     *  Define a path to navigate.
     *  @param
     *  ```javascript
     *  
     *  ```
     */
    func:function()
    {
        var a = [].slice.call(arguments, 0);
        if(a.length == 1 ? dd.isObject(a[0]) : false)
        {
            this.func(a[0].url, a[0].success);
        }
        else
        {
            if((a.length == 2 ? dd.is(a[1], "function") || a[1] === null : false))
            {
                if(a[1] === null)
                {
                    this.remove(a[0]);
                }
                else
                {
                    this.add(a[0], a[1]);
                }
            }
            else
            {
                var h = a.join("/");
                if(history.pushState)
                {
                    history.pushState({}, "", "/" + (h == "" ? "" : h + "/"));
                }
                else
                {
                    document.location.hash = "!/" + (h == "" ? "" : h + "/");
                }
                this.load(a);
            }
        }
        return true;
    },
    test:function(r, c)
    {
        return r == "*" ? true : this.match(r, c).matched;
    },
    match:function(r, c)
    {
        if(!dd.is(c) || r == "*")
        {
            return {matched:true};
        }
        else if(r === "" & c !== "")
        {
            return {matched:false};
        }
        var m = {};     // Matches
        var n = false;  // Name
        var np = false; // Name Parentheses
        var t = r.split("");
        var vn = "";
        var vnp = "";
        for(var i = 0; i < t.length; i++)
        {
            if(t[i] == "(" && t[i + 1] == "<")
            {
                i++;
                n = true;
                np = true;
            }
            else if(t[i] == ">" && n && np)
            {
                n = false;
            }
            else if(t[i] == ")" && !n && np)
            {
                m[vn] = vnp;
                r = r.replace("(<" + vn + ">" + vnp + ")", "(" + vnp + ")");
                vn = "";
                vnp = "";
                np = false;
            }
            else if(n && np)
            {
                vn += t[i];
            }
            else if(!n && np)
            {
                vnp += t[i];
            }
        }
        var mm = (c + "").match(new RegExp(r));
        if(mm === null)
        {
            m.matched = false;
            for(var i in m)
            {
                m[i] = null;
            }
        }
        else
        {
            m.matched = true;
            var j = 0;
            for(var i in m)
            {
                if(i != "matched")
                {
                    j++;
                    m[i] = mm[j];
                }
            }
        }
        return m;
    },
    _a:[],
    add:function(n, f)
    {
        var t = n.split("/");
        t = t.slice(1, t[t.length - 1] == "" ? -1 : t.length);
        t = t.length > 0 ? t : [""];
        this._a.push({
            r:t,
            f:f
        });
    },
    remove:function(n)
    {
        var v = n.split("/");
        if(v[0] == "")
        {
            v.shift();
        }
        for(var i in this._a)
        {
            if(this._a[i].r.join("/") == v.join("/"))
            {
                this._a.splice(i, 1);
                break;
            }
        }
    },
    failure:function(){},
    event:function(o)
    {
        if("failure" in o)
        {
            this.failure = o.failure;
        }
    },
    load:function(v)
    {
        var h = document.location.href.match(/\/.+?(?!\/#!)\/(.*)$/);
        h = h === null ? "" : h[1];
        v = v || h.split("/").pop() == ""
            ? h.split("/").slice(0, -1)
            : h.split("/");
        v = v.length > 0 ? v : [""];
        for(var x = 0; x < this._a.length; x++)
        {
            var matches = {};
            if(this._a[x].r.length == 0 && v.length == 1 && v[0] == "")
            {
                this._a[x].f.call({});
            }
            for(var i = 0; i < this._a[x].r.length; i++)
            {
                var m = this.match(this._a[x].r[i], v[i]);
                for(var j in m)
                {
                    if(j != "matched")
                    {
                        matches[j] = m[j];
                    }
                }
                if(!m.matched)
                {
                    break;
                }
                else if(i == v.length - 1 || this._a[x].r[i] == "*")
                {
                    dd.navigate.path = v;
                    this._a[x].f.call(matches);
                    return true;
                }
            }
        }
        this.failure.call({});
        return false;
    }
});